//
//  ViewController.m
//  opengl_learn2
//
//  Created by Daruo258 on 2021/10/30.
//  Copyright © 2021年 Daruo258. All rights reserved.
//

#import "ViewController.h"

/*
 1)glGenBuffers()  创建gpu buffer
 2)glBindBuffer()  绑定buffer,让GL_ARRAY_BUFFER指向创建的buffer 以让buffer生效
 3)glBufferData()  让cup 发送顶点数据到gpu
 4)glDrawArrays() 开始绘制
 gpu如何知道如何解释顶点信息 :shader vertex fragment shader
 small little programs
 can perform shading lighting and special effects
 they are not run on cpu ,they run on graphics card then cpu combined and progress them
 
 vertex shader:
 input a_Postion
 output gl_Posiotn
 
 fragment shader:
 outpus gl_FragColor
 
 
 glEnableVertexAttribArray:turn attribute on
 glVertexAttribPoint: where is it in the vertex buffer
 
 */

/*
 what is ...
 1) an OpenGL context?
 you think of it as a scratch pad for it‘s keeping track of the various things open gl needs
 to know in order to render things to the screen
 it also keeps track of the current state of things so if you stop the clear color or
 something it's going to stay that until you change it later and so on
 ot also has a certain API level associated with it which will be using 2.0 to this
 working
 2) a vertex attibute?
 a vertex attibute can think of as an input variable to a vertex shader
 3) a vertex buffer object?
 this is a buffer of infomation about vertices that are stored on the GPU
 4) the thre API calls needed to send vertex data from cpu to gpu
 1 create the buffer with you gpu buffer then you have to bind it is active with gl bind buffer
 then finally have to send the data from cpu to the actively bind buffer with gl buffer data fanally
 
 5) the difference between a vertex ahader and fragment shader
 vertext shader is called once per vertex its job is output the final position of the vertex
 fragment shader is called once per render pixel sort of and its job is to outpout the
 final color of that pixel
 
 */

#import "RWTVertex.h"
#import "RWTBaseEffect.h"

@interface ViewController ()

@end

@implementation ViewController {
    GLuint _vertexBuffer;
    RWTBaseEffect * _shader;
}

-(void)setupVertexBuffer {
    const static RWTVertex vertices[] = {
        {{-1,-1,0}},//A
        {{1.0,-1.0,0}},//B
        {{0,0,0}},//C
    };
    
//    glGenBuffers(<#GLsizei n#>, <#GLuint *buffers#>)
    glGenBuffers(1, &_vertexBuffer);// 生成一个gpu buffer
//    glBindBuffer(<#GLenum target#>, <#GLuint buffer#>)
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
//    glBufferData(<#GLenum target#>, <#GLsizeiptr size#>, <#const GLvoid *data#>, <#GLenum usage#>)
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
}

-(void)setupShader {
    _shader = [[RWTBaseEffect alloc] initWithVertexShader:@"RWTSimpleVertex.glsl" fragmentShader:@"RWTSimpleFragment.glsl"];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    GLKView *view = (GLKView*)self.view;
    view.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    [EAGLContext setCurrentContext:view.context];
    [self setupShader];
    [self setupVertexBuffer];
}

-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect{
    glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    
    [_shader prepareToDraw];
    
    //激活顶点属性
    glEnableVertexAttribArray(RWTVertexAttribPosition);
    //gpu 顶点信息从哪里开始
//    glVertexAttribPointer(<#GLuint indx#>, <#GLint size#>, <#GLenum type#>, <#GLboolean normalized#>, <#GLsizei stride#>, <#const GLvoid *ptr#>)
    glVertexAttribPointer(RWTVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(RWTVertex), (const GLvoid *)offsetof(RWTVertex, Position));
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
//    glDrawArrays(<#GLenum mode#>, <#GLint first#>, <#GLsizei count#>)
    glDrawArrays(GL_TRIANGLES, 0, 3);
    
    glDisableVertexAttribArray(RWTVertexAttribPosition);
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end
